package org.jeecg.modules.platform.organization.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.ServiceNameConstants;
import org.jeecg.common.system.api.entity.SysPermission;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.api.*;
import org.jeecg.modules.platform.api.PlatformOrganizationApi;
import org.jeecg.modules.platform.entity.CyPlatformOrganizationAndMember;
import org.jeecg.modules.platform.entity.CyPlatformOrganizationInfo;
import org.jeecg.modules.platform.entity.CyPlatformOrganizationPermission;
import org.jeecg.modules.platform.member.service.ICyPlatformOrganizationAndMemberService;
import org.jeecg.modules.platform.organization.service.ICyPlatformOrganizationInfoService;
import org.jeecg.modules.platform.organization.service.ICyPlatformOrganizationPermissionService;
import org.jeecg.modules.platform.request.PlatformOrganizationInfoAuth;
import org.jeecg.modules.system.service.*;
import org.jeecg.modules.user.entity.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 平台组织管理
 * @Author: jeecg-boot
 * @Date: 2024-10-25
 * @Version: V1.0
 */
@Api(tags = "平台组织管理")
@RestController
@RequestMapping(ServiceNameConstants.PATH_ORGANIZATION)
@Slf4j
public class CyPlatformOrganizationInfoController extends JeecgController<CyPlatformOrganizationInfo, ICyPlatformOrganizationInfoService> implements PlatformOrganizationApi {
    @Autowired
    private ICyPlatformOrganizationInfoService cyPlatformOrganizationInfoService;

    @Autowired
    private ICyPlatformOrganizationPermissionService organizationPermissionService;

    @Autowired
    private ICyPlatformOrganizationAndMemberService orgMemberService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ISysPermissionService permissionService;
    @Autowired
    private ISysRoleService roleService;
    @Autowired
    private ISysDictService sysDictService;


    /**
     * 分页列表查询
     *
     * @param cyPlatformOrganizationInfo
     * @param pageNo
     * @param pageSize
     * @param req
     *
     * @return
     */
    //@AutoLog(value = "平台组织管理-分页列表查询")
    @ApiOperation(value = "平台组织管理-分页列表查询", notes = "平台组织管理-分页列表查询")
//    @RequiresPermissions("platform:organization:list")
    @GetMapping(value = "/list")
    public Result<IPage<CyPlatformOrganizationInfo>> queryPageList(CyPlatformOrganizationInfo cyPlatformOrganizationInfo,
                                                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                                   HttpServletRequest req) {
        QueryWrapper<CyPlatformOrganizationInfo> queryWrapper = QueryGenerator.initQueryWrapper(cyPlatformOrganizationInfo, req.getParameterMap());
        Page<CyPlatformOrganizationInfo> page = new Page<>(pageNo, pageSize);
        IPage<CyPlatformOrganizationInfo> pageList = cyPlatformOrganizationInfoService.page(page, queryWrapper);

        // 添加模块权限列表
        if (CollectionUtils.isNotEmpty(pageList.getRecords())) {
            List<String> orgIds = pageList.getRecords().stream().map(CyPlatformOrganizationInfo::getId).collect(Collectors.toList());
            List<CyPlatformOrganizationPermission> list = organizationPermissionService.list(new LambdaQueryWrapper<CyPlatformOrganizationPermission>().in(CyPlatformOrganizationPermission::getOrganizationId, orgIds));
            Map<String, List<CyPlatformOrganizationPermission>> permissionMap = list.stream().collect(Collectors.groupingBy(CyPlatformOrganizationPermission::getOrganizationId));
            pageList.getRecords().parallelStream().forEach(item -> item.setSelectModules(permissionMap.get(item.getId())));
        }

        return Result.OK(pageList);
    }

    /**
     * 添加
     *
     * @param organizationInfo
     *
     * @return
     */
    @AutoLog(value = "平台组织管理-后台主动添加")
    @ApiOperation(value = "平台组织管理-添加", notes = "平台组织管理-添加")
//    @RequiresPermissions("platform:organization:add")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody CyPlatformOrganizationInfo organizationInfo) {

        //判用户否已经绑定其他且也
        List<CyPlatformOrganizationInfo> list = cyPlatformOrganizationInfoService.list(new LambdaQueryWrapper<CyPlatformOrganizationInfo>()
                .eq(CyPlatformOrganizationInfo::getApproveUser, organizationInfo.getApproveUser()));
        if (CollUtil.isNotEmpty(list)){
            return Result.error("该用户已认证其他企业!");
        }

        String orgId = IdWorker.getIdStr();
        organizationInfo.setId(orgId);
        // 注册组织和部门
        String deptId = this.service.register(organizationInfo);




        // 开通相关模块及权限
        if (CollectionUtils.isNotEmpty(organizationInfo.getSelectModules())) {
            organizationPermissionService.saveBatch(organizationInfo.getId(), organizationInfo.getSelectModules());
        }

        String approveUserId = organizationInfo.getApproveUser();
        SysUser approveUser = userService.getById(approveUserId);
        // 更新用户信息
        if (StringUtils.isEmpty(approveUser.getOrganizationId())) {
            userService.updateById(new SysUser().setId(approveUserId).setDepartId(deptId).setOrganizationId(orgId));
            redisUtil.del(CacheConstant.SYS_USERS_CACHE + "::" + approveUser.getUsername());
        }

        // 绑定组织和用户关系
        orgMemberService.save(new CyPlatformOrganizationAndMember().setOrganizationId(orgId).setUserId(approveUserId).setDefaultBind(true));

        // 创建超级管理员并绑定认证人
        roleService.createAdmin(approveUserId, deptId, orgId);

        return Result.OK("认证成功！");
    }

    /**
     * 注册企业
     *
     * @param platformOrganizationInfoAuth
     *
     * @return
     */
    @AutoLog(value = "平台组织管理-注册企业")
    @ApiOperation(value = "平台组织管理-注册企业", notes = "平台组织管理-注册企业")
//    @RequiresPermissions("platform:organization:add")
    @PostMapping(value = "/auth")
    public Result<?> auth(@RequestBody PlatformOrganizationInfoAuth platformOrganizationInfoAuth) {
        CyPlatformOrganizationInfo organizationInfo = BeanUtil.toBean(platformOrganizationInfoAuth, CyPlatformOrganizationInfo.class);

        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        organizationInfo.setContactNumber(loginUser.getPhone());
        organizationInfo.setApproveUser(loginUser.getId());
        organizationInfo.setAllowLevel(1);
        organizationInfo.setCostCalculationSubject(1);
        organizationInfo.setType(1);
        organizationInfo.setState(2);
        organizationInfo.setApproveDate(new Date());

        //判用户否已经绑定其他且也
        List<CyPlatformOrganizationInfo> list = cyPlatformOrganizationInfoService.list(new LambdaQueryWrapper<CyPlatformOrganizationInfo>()
                .eq(CyPlatformOrganizationInfo::getApproveUser, organizationInfo.getApproveUser()));
        if (CollUtil.isNotEmpty(list)){
            return Result.error("该用户已认证其他企业!");
        }

        //校验邮箱验证码是否正确
       /* String redisKey = CommonConstant.EMAIL_REDIS_KEY_PRE+organizationInfo.getContactMail();
        Object captcha = redisUtil.get(redisKey);
        if (captcha == null){
            return Result.error("邮箱验证码已过期!");
        }
        if (!captcha.equals(platformOrganizationInfoAuth.getCaptcha())){
            return Result.error("邮箱验证码错误!");
        }*/

        String orgId = IdWorker.getIdStr();
        organizationInfo.setId(orgId);
        // 注册组织和部门
        String deptId = this.service.register(organizationInfo);

        List<SysPermission> sysPermissions = permissionService.listModulesTree(false);

        List<CyPlatformOrganizationPermission> platformOrganizationPermissions = sysPermissions.stream().filter(sysPermission -> !sysPermission.getUrl().matches(".*module_admin.*")).map(sysPermission ->
                new CyPlatformOrganizationPermission().setOrganizationId(orgId)
                        .setModuleId(sysPermission.getId())
                        .setExpire(DateUtil.offsetDay(new Date(), 7))
        ).collect(Collectors.toList());

        organizationPermissionService.saveBatch(organizationInfo.getId(), platformOrganizationPermissions);


        String approveUserId = organizationInfo.getApproveUser();
        SysUser approveUser = userService.getById(approveUserId);
        // 更新用户信息
        approveUser.setId(approveUserId);
        approveUser.setDepartId(deptId);
        approveUser.setOrganizationId(orgId);
        approveUser.setRealname(organizationInfo.getContactUser());
        approveUser.setEmail(organizationInfo.getContactMail());
        userService.updateById(approveUser);
        redisUtil.del(CacheConstant.SYS_USERS_CACHE + "::" + approveUser.getUsername());

        // 绑定组织和用户关系
        orgMemberService.save(new CyPlatformOrganizationAndMember().setOrganizationId(orgId).setUserId(approveUserId).setDefaultBind(true));

        // 创建超级管理员并绑定认证人
        roleService.createAdmin(approveUserId, deptId, orgId);
        approveUser.setIsOrgAdmin(true);

        JSONObject obj = new JSONObject();
        obj.put("userInfo", approveUser);
        obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
        return Result.OK("添加成功！",obj);
    }

    /**
     * 编辑
     *
     * @param organizationInfo
     *
     * @return
     */
    @AutoLog(value = "平台组织管理-编辑")
    @ApiOperation(value = "平台组织管理-编辑", notes = "平台组织管理-编辑")
//    @RequiresPermissions("platform:organization:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody CyPlatformOrganizationInfo organizationInfo) {

        //判用户否已经绑定其他且也
        List<CyPlatformOrganizationInfo> list = cyPlatformOrganizationInfoService.list(new LambdaQueryWrapper<CyPlatformOrganizationInfo>()
                .eq(CyPlatformOrganizationInfo::getApproveUser, organizationInfo.getApproveUser())
                .ne(CyPlatformOrganizationInfo::getId,organizationInfo.getId()));

        if (CollUtil.isNotEmpty(list)){
            return Result.OK("该用户已认证其他企业!");
        }

        // 更新信息
        cyPlatformOrganizationInfoService.updateById(organizationInfo);

        // 更新权限
        organizationPermissionService.update(organizationInfo.getId(),organizationInfo.getApproveUser(), organizationInfo.getSelectModules());

        return Result.OK("编辑成功!");
    }

    /**
     * 检查名称是否重复
     *
     * @param organizationInfo
     *
     * @return
     */
    @AutoLog(value = "平台组织管理-检查名称是否重复")
    @ApiOperation(value = "平台组织管理-检查名称是否重复", notes = "平台组织管理-检查名称是否重复")
    @RequestMapping(value = "/checkName", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<Boolean> checkName(@RequestBody CyPlatformOrganizationInfo organizationInfo) {
        List<CyPlatformOrganizationInfo> list = cyPlatformOrganizationInfoService.list(
                new LambdaQueryWrapper<CyPlatformOrganizationInfo>()
                        .ne(StringUtils.isNotEmpty(organizationInfo.getId()),CyPlatformOrganizationInfo::getId, organizationInfo.getId())
                        .eq(CyPlatformOrganizationInfo::getName, organizationInfo.getName()));
        return Result.OK(CollUtil.isNotEmpty(list));
    }

    /**
     * 通过id删除
     *
     * @param id
     *
     * @return
     */
    @AutoLog(value = "平台组织管理-通过id删除")
    @ApiOperation(value = "平台组织管理-通过id删除", notes = "平台组织管理-通过id删除")
//    @RequiresPermissions("platform:organization:delete")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        cyPlatformOrganizationInfoService.removeById(id);
        organizationPermissionService.remove(new LambdaQueryWrapper<CyPlatformOrganizationPermission>().eq(CyPlatformOrganizationPermission::getOrganizationId, id));
        return Result.OK("删除成功!");
    }


    /**
     * 通过id查询
     *
     * @param id
     *
     * @return
     */
    //@AutoLog(value = "平台组织管理-通过id查询")
    @ApiOperation(value = "平台组织管理-通过id查询", notes = "平台组织管理-通过id查询")
//    @RequiresPermissions("platform:organization:queryById")
    @GetMapping(value = "/queryById")
    public Result<CyPlatformOrganizationInfo> queryById(@RequestParam(name = "id", required = true) String id) {
        CyPlatformOrganizationInfo cyPlatformOrganizationInfo = cyPlatformOrganizationInfoService.getById(id);
        if (cyPlatformOrganizationInfo == null) {
            return Result.error("未找到对应数据");
        }
        List<CyPlatformOrganizationPermission> list = organizationPermissionService.list(new LambdaQueryWrapper<CyPlatformOrganizationPermission>().eq(CyPlatformOrganizationPermission::getOrganizationId, id));
        cyPlatformOrganizationInfo.setSelectModules(list);
        return Result.OK(cyPlatformOrganizationInfo);
    }

    /**
     * 通过手机号查询
     *
     * @param phone
     *
     * @return
     */
    //@AutoLog(value = "平台组织管理-通过id查询")
    @ApiOperation(value = "平台组织管理-通过手机号查询", notes = "平台组织管理-通过手机号查询")
//    @RequiresPermissions("platform:organization:queryById")
    @GetMapping(value = "/queryByPhone")
    public Result<CyPlatformOrganizationInfo> queryByPhone(@RequestParam(name = "phone", required = true) String phone) {
        LambdaQueryWrapper<CyPlatformOrganizationInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CyPlatformOrganizationInfo::getContactNumber, phone);
        CyPlatformOrganizationInfo cyPlatformOrganizationInfo = cyPlatformOrganizationInfoService.getOne(wrapper,false);
        return Result.OK(cyPlatformOrganizationInfo);
    }


    @AutoLog(value = "平台组织管理-编辑基础信息")
    @ApiOperation(value = "平台组织管理-编辑基础信息", notes = "平台组织管理-编辑")
    @RequestMapping(value = "/editBaseInfo", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> editBaseInfo(@RequestBody CyPlatformOrganizationInfo organizationInfo) {
        cyPlatformOrganizationInfoService.updateById(organizationInfo);
        return Result.OK("编辑成功!");
    }


    @ApiOperation(value = "查看当前用户的组织信息")
    @GetMapping(value = "current")
    public Result<CyPlatformOrganizationInfo> queryCurrent() {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (StringUtils.isEmpty(loginUser.getOrganizationId())) {
            return Result.error("用户未注册组织");
        }
        CyPlatformOrganizationInfo cyPlatformOrganizationInfo = cyPlatformOrganizationInfoService.
                getById(loginUser.getOrganizationId());
        if (cyPlatformOrganizationInfo == null) {
            return Result.error("未注册组织");
        }
        // 查询模块
        List<CyPlatformOrganizationPermission> organizationPermissions = organizationPermissionService.list(new LambdaQueryWrapper<CyPlatformOrganizationPermission>().eq(CyPlatformOrganizationPermission::getOrganizationId, loginUser.getOrganizationId()));

        // 模块名称查询
        List<SysPermission> sysPermissionList = permissionService.listModulesTree(false);
        Map<String, SysPermission> moduleMap = sysPermissionList.stream().collect(Collectors.toMap(SysPermission::getId, Function.identity()));
        organizationPermissions.parallelStream()
                .filter(item -> moduleMap.containsKey(item.getModuleId()))
                .forEach(item -> {
                    SysPermission sysPermission = moduleMap.get(item.getModuleId());

                    item.setModuleName(sysPermission.getName());
                    item.setUrl(sysPermission.getUrl());
                });


        cyPlatformOrganizationInfo.setSelectModules(organizationPermissions);
        return Result.OK(cyPlatformOrganizationInfo);
    }

    @ApiOperation(value = "用户注册企业")
    @RequestMapping(value = "/register", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> register(@RequestBody CyPlatformOrganizationInfo organizationInfo) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        organizationInfo.setId(IdWorker.getIdStr());
        organizationInfo.setCostCalculationSubject(1);
        organizationInfo.setAllowLevel(1);
        organizationInfo.setApproveUser(loginUser.getId());
        organizationInfo.setState(1);
        // 注册组织和部门
        String deptId = cyPlatformOrganizationInfoService.register(organizationInfo);

        // 更新组织用户
        this.service.updateUserOrganizationId(organizationInfo.getId(), deptId);

        // 注册组织权限
        organizationPermissionService.registerPermission(organizationInfo.getId());

        // 创建超级管理员并绑定认证人
        roleService.createAdmin(loginUser.getId(), deptId, organizationInfo.getId());

        return Result.OK("注册成功");
    }

    @Override
    public Result<CyPlatformOrganizationInfo> getById(String id) {
        CyPlatformOrganizationInfo cyPlatformOrganizationInfo = cyPlatformOrganizationInfoService.getById(id);
        return Result.ok(cyPlatformOrganizationInfo);
    }

}
